package com.dyyx.nettyrpc.protocol;

import java.text.SimpleDateFormat;
import java.util.HashMap;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;


public class JsonUtil {
    private static ObjectMapper objMapper = new ObjectMapper();

    static {
        SimpleDateFormat dateFormat = new SimpleDateFormat(
                "yyyy-MM-dd HH:mm:ss");
        objMapper.setDateFormat(dateFormat);
        objMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        objMapper.enable(SerializationFeature.INDENT_OUTPUT);
        objMapper.configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET, false);
        objMapper.configure(JsonGenerator.Feature.AUTO_CLOSE_JSON_CONTENT, false);
        objMapper.disable(SerializationFeature.FLUSH_AFTER_WRITE_VALUE);
        objMapper.disable(SerializationFeature.CLOSE_CLOSEABLE);
        objMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
        objMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
        objMapper.configure(JsonParser.Feature.IGNORE_UNDEFINED, true);
    }

    public static <T> byte[] serialize(T obj) {
        try {
        	byte[] bytes = objMapper.writeValueAsBytes(obj);
        	return bytes;
        } catch (Exception e) {
            throw new RuntimeException("serialize error", e);
        }
    }

    public static <T> T deserialize(byte[] data, Class<T> cls) {
        try {
            T obj = objMapper.readValue(data, cls);
            return obj;
        } catch (Exception e) {
            throw new RuntimeException("deserialize error", e);
        }
    }

    public static <T> T jsonToObject(String json, Class<?> cls) {
        JavaType javaType = objMapper.getTypeFactory().constructType(cls);
        try {
            T obj = objMapper.readValue(json, javaType);
            return obj;
        } catch (Exception e) {
            throw new RuntimeException("jsonToObject error", e);
        }
    }

    public static <T> T jsonToObjectList(String json,
                                               Class<?> collectionClass, Class<?>... elementClass) {
        JavaType javaType = objMapper.getTypeFactory().constructParametricType(
                collectionClass, elementClass);
        try {
            T obj = objMapper.readValue(json, javaType);
            return obj;
        } catch (Exception e) {
            throw new RuntimeException("jsonToObjectList error", e);
        }
    }

    public static <T> T jsonToObjectHashMap(String json,
                                                  Class<?> keyClass, Class<?> valueClass) {
        JavaType javaType = objMapper.getTypeFactory().constructParametricType(HashMap.class, keyClass, valueClass);
        try {
            T obj = objMapper.readValue(json, javaType);
            return obj;
        } catch (Exception e) {
            throw new RuntimeException("jsonToObjectHashMap error", e);
        }
    }

    public static String objectToJson(Object o) {
        try {
            String json = objMapper.writeValueAsString(o);
            return json;
        } catch (Exception e) {
            throw new RuntimeException("objectToJson error", e);
        }
    }
}
